home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #5 / Amiga Plus CD - 2000 - No. 5.iso / Tools / Dev / FPSE_src / system / amiga / plugin / cd / cd.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-01  |  5.1 KB  |  262 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. #include <exec/types.h>
  5. #include <exec/memory.h>
  6. #include <devices/trackdisk.h>
  7. #include <devices/scsidisk.h>
  8.  
  9. #include <powerup/ppcproto/intuition.h>
  10. #include <powerup/ppclib/interface.h>
  11. #include <powerup/ppclib/time.h>
  12. #include <powerup/gcclib/powerup_protos.h>
  13. #include <powerup/ppcproto/exec.h>
  14. #include <powerup/ppcproto/dos.h>
  15. #include <powerup/ppcinline/alib.h>
  16.  
  17. #include "fpse.h"
  18. #include "scsidefs.h"
  19.  
  20. #define READ_CD 0xbe
  21.  
  22. #define SENSELEN 32
  23. unsigned char sensebuf[SENSELEN];
  24.  
  25. extern int amiga_cd_unit;
  26. extern char *amiga_cd_device;
  27.  
  28. struct MsgPort *CDMP; /* Pointer for message port */
  29. struct IOExtTD *CDIO; /* Pointer for IORequest */
  30. int cd_error;
  31.  
  32. typedef struct {
  33.   unsigned char reserved;
  34.   unsigned char adr;
  35.   unsigned char trackno;
  36.   unsigned char reserved1;
  37.   unsigned char addr[4];
  38. } TOCENTRY;
  39.  
  40. typedef struct {
  41.   unsigned char size[2];
  42.   unsigned char first;
  43.   unsigned char last;
  44.   TOCENTRY track[100];
  45. } TOC;
  46.  
  47. typedef struct {
  48.   UINT8 minute;
  49.   UINT8 second;
  50.   UINT8 frame;
  51. } LOC;
  52.  
  53. #define INT2BCD(a) (((a)/10)*16+((a)%10))
  54. #define BCD2INT(a) (((a)>>4)*10+((a)&0xf))
  55.  
  56. #define SECTOR_SIZE 2352
  57. static UINT8 readbuf[SECTOR_SIZE*2];
  58.  
  59. static int loc2int(LOC *loc);
  60. static void ExecReadTOC(void *buf,int size,int first);
  61. static void ExecRead(unsigned long frame,void *buf,int bufsize);
  62. static void ExecPlay(unsigned char *start,unsigned char *end);
  63. static void ExecStop(void);
  64.  
  65. static char *DefaultCDDevice = "atapi.device";
  66.  
  67. int CD_Open(UINT32 *par)
  68. {
  69.   if (amiga_cd_device == NULL) {
  70.     amiga_cd_device = DefaultCDDevice;
  71.   }
  72.  
  73.   CDMP = CreateMsgPort();
  74.   if (CDMP != NULL) {
  75.     CDIO = (struct IOExtTD *)CreateIORequest(CDMP, sizeof(struct IOExtTD));
  76.     if (CDIO != NULL) {
  77.       cd_error = OpenDevice(amiga_cd_device, amiga_cd_unit, (struct IORequest *)CDIO, 0);
  78.       if (cd_error != 0) {
  79.         printf("CD_Open: could not open device %s unit %d\n", amiga_cd_device, amiga_cd_unit);
  80.         return FPSE_ERR;
  81.       }
  82.     }
  83.   }
  84.  
  85.   return FPSE_OK;
  86. }
  87.  
  88. void CD_Close(void)
  89. {
  90.   if (cd_error == 0) {
  91.     CloseDevice(CDIO);
  92.   }
  93.  
  94.   if (CDIO != NULL) {
  95.     DeleteIORequest(CDIO);
  96.   }
  97.  
  98.   if (CDMP != NULL) {
  99.     DeleteMsgPort(CDMP);
  100.   }
  101. }
  102.  
  103. static TOC toc;
  104.  
  105. static struct {
  106.   unsigned char size[2];
  107.   unsigned char first,last;
  108.   TOCENTRY track[1];
  109. } readout;
  110.  
  111. int CD_GetTN(UINT8 *result)
  112. {
  113.   ExecReadTOC(&toc,sizeof(toc),0);
  114.  
  115.   result[1] = toc.first;
  116.   result[2] = toc.last;
  117.  
  118.   return 0;
  119. }
  120.  
  121. int CD_GetTD(UINT8 *result,int track)
  122. {
  123.   int n;
  124.  
  125.   ExecReadTOC(&toc,sizeof(toc),0);
  126.   n = track-toc.first;
  127.  
  128.   result[1] = toc.track[n].addr[1]; /* minute */
  129.   result[2] = toc.track[n].addr[2]; /* second */
  130.   result[3] = toc.track[n].addr[3]; /* frame */
  131.  
  132.   return 0;
  133. }
  134.  
  135. int CD_Play(UINT8 *param)
  136. {
  137.   /* serch next track */
  138.   ExecPlay(param,&readout.track[0].addr[2]);
  139.   return 0;
  140. }
  141.  
  142. int CD_Stop(void)
  143. {
  144.   /* serch next track */
  145.   ExecStop();
  146.   return 0;
  147. }
  148.  
  149. UINT8 *CD_Read(UINT8 *param)
  150. {
  151.   ExecRead(loc2int((LOC *)param),readbuf+12,SECTOR_SIZE);
  152.  
  153.   /* emulate header */
  154.   readbuf[0] = INT2BCD(param[0]);
  155.   readbuf[1] = INT2BCD(param[1]);
  156.   readbuf[2] = INT2BCD(param[2]);
  157.  
  158.   return readbuf;
  159. }
  160.  
  161. void CD_GetSeek(UINT8 *par)
  162. {
  163. }
  164.  
  165. int ExecSCSICmd(UINT8 *cmd,int cmdsize,UINT8 *data,int datasize, UINT8 direction)
  166. {
  167.   struct SCSICmd scmd;
  168.  
  169.   CDIO->iotd_Req.io_Command = HD_SCSICMD;
  170.   CDIO->iotd_Req.io_Data    = &scmd;
  171.   CDIO->iotd_Req.io_Length  = sizeof(scmd);
  172.  
  173.   scmd.scsi_Data        = (APTR)data;
  174.   scmd.scsi_Length      = datasize;
  175.   scmd.scsi_SenseActual = 0;
  176.   scmd.scsi_SenseData   = sensebuf;
  177.   scmd.scsi_SenseLength = SENSELEN;
  178.   scmd.scsi_Command     = cmd;
  179.   scmd.scsi_CmdLength   = cmdsize;
  180.   scmd.scsi_Flags       = SCSIF_AUTOSENSE | direction;
  181.  
  182.   DoIO((struct IORequest *)CDIO);
  183.  
  184.   if (CDIO->iotd_Req.io_Error != 0) {
  185.     printf("ExecSCSICmd: error (%d)\n", CDIO->iotd_Req.io_Error);
  186.     printf("SCSI Status: %d\n", scmd.scsi_Status);
  187.   }
  188.  
  189.   return CDIO->iotd_Req.io_Error;
  190. }
  191.  
  192. int CD_Wait()
  193. {
  194.   /* What is this supposed to do ? */
  195.   return FPSE_OK;
  196. }
  197.  
  198. static int loc2int(LOC *loc)
  199. {
  200.   return ((loc->minute)*60+(loc->second)-2)*75+(loc->frame);
  201. }
  202.  
  203. static void ExecReadTOC(void *buf,int size,int first)
  204. {
  205.   UINT8 cdb[10];
  206.  
  207.   memset(cdb,0,sizeof(cdb));
  208.  
  209.   cdb[0] = SCSI_READ_TOC;
  210.   cdb[1] = 2; /* MSF format */
  211.   cdb[6] = first;
  212.   cdb[7] = size>>8;
  213.   cdb[8] = size&255;
  214.  
  215.   ExecSCSICmd(cdb,sizeof(cdb),buf,size,SCSIF_READ);
  216. }
  217.  
  218. static void ExecRead(unsigned long frame,void *buf,int bufsize)
  219. {
  220.   UINT8 cdb[12];
  221.  
  222.   memset(cdb,0,sizeof(cdb));
  223.  
  224.   cdb[0] = READ_CD;
  225.   cdb[2] = frame>>24;
  226.   cdb[3] = frame>>16;
  227.   cdb[4] = frame>>8;
  228.   cdb[5] = frame;
  229.   cdb[8] = 1; /* read 1 frame */
  230.   cdb[9] = 0x18; /* User Data + EDC/ECC */
  231.  
  232.   ExecSCSICmd(cdb,sizeof(cdb),buf,bufsize,SCSIF_READ);
  233. }
  234.  
  235. static void ExecPlay(unsigned char *start,unsigned char *end)
  236. {
  237.   UINT8 cdb[10];
  238.  
  239.   memset(cdb,0,sizeof(cdb));
  240.  
  241.   cdb[0] = SCSI_PLAYAUDMSF;
  242.   cdb[3] = start[0];
  243.   cdb[4] = start[1];
  244.   cdb[5] = start[2];
  245.   cdb[6] = end[0];
  246.   cdb[7] = end[1];
  247.   cdb[8] = end[2];
  248.  
  249.   ExecSCSICmd(cdb,sizeof(cdb),NULL,0,SCSIF_READ);
  250. }
  251.  
  252. static void ExecStop(void)
  253. {
  254.   UINT8 cdb[10];
  255.  
  256.   memset(cdb,0,sizeof(cdb));
  257.  
  258.   cdb[0] = 0x4B; /* Pause command */
  259.   cdb[8] = 0; /* 0:pause 1:resume */
  260.  
  261.   ExecSCSICmd(cdb,sizeof(cdb),NULL,0,SCSIF_READ);
  262. }